﻿#ifndef SIMUVALUE_H
#define SIMUVALUE_H

#include <QDebug>
#include <QRandomGenerator>
#include <QtMath>

class AbstractSimuValue
{
public:
    virtual ~AbstractSimuValue() {}

    virtual QString produce() = 0;
};

class ConstSimuValue : public AbstractSimuValue
{
public:
    ConstSimuValue(const int initValue) {
        m_value = initValue;
    }

    QString produce() override {
        return QString::number(m_value);
    }

private:
    int m_value;
};

class AssignSimuValue : public AbstractSimuValue
{
public:
    AssignSimuValue(const QString currentValue) {
        m_value = currentValue;
    }

    QString produce() override {
        return m_value;
    }

private:
    QString m_value;
};

class IncreaseSimuValue : public AbstractSimuValue
{
public:
    IncreaseSimuValue(const QString currentValue, const QString dataType, const int increaseStep) {
        m_value = currentValue.toInt() + increaseStep;
        if (QString::compare(dataType, "uc", Qt::CaseInsensitive) == 0) {
            m_value = m_value & 0xFF;
        } else if (QString::compare(dataType, "us", Qt::CaseInsensitive) == 0) {
            m_value = m_value & 0xFFFF;
        } else {
        }
    }

    QString produce() override {
        return QString::number(m_value);
    }

private:
    int m_value;
};

class SinSimuValue : public AbstractSimuValue
{
public:
    SinSimuValue(const double value) {
        m_value = value;
    }

    SinSimuValue(const qint64 timeSpan, const double sinT, const double sinA, const bool sinSquare) {
        // sinT表示周期, sinA表示振幅
        m_value = qSin(timeSpan / 1000. / sinT * 2 * M_PI) * sinA;
        if (sinSquare) {
            double halfA = sinA / 2;
            if (m_value > halfA)
                m_value = sinA;
            else if (m_value < -halfA)
                m_value = -sinA;
            else
                m_value = 0;
        }
    }

    QString produce() override {
        return QString::number(m_value, 'f', 2);
    }

private:
    double m_value;
};

class RandomSimuValue : public AbstractSimuValue
{
public:
    RandomSimuValue(const double minValue, const double maxValue) {
        m_value = QRandomGenerator::global()->generateDouble() * (maxValue - minValue) + minValue;
    }

    QString produce() override {
        return QString::number(m_value, 'f', 2);
    }

private:
    double m_value;
};


#endif // SIMUVALUE_H
